Skip to content

chore: k6 부하테스트 시나리오 고도화 및 모니터링 대시보드 개선 - #105

Merged
docodocod merged 2 commits into
developfrom
feat/k6-test-advancement
May 29, 2026
Merged

chore: k6 부하테스트 시나리오 고도화 및 모니터링 대시보드 개선#105
docodocod merged 2 commits into
developfrom
feat/k6-test-advancement

Conversation

@docodocod

Copy link
Copy Markdown
Contributor
  • 01·03·05·06·07번: event_spike(워밍업 후 스파이크) + ramp_up(점진 증가) 두 시나리오 적용
  • 04번: ramp_up 단독으로 서킷브레이커 OPEN 시점 탐색 시나리오로 개선
  • docker-compose.prod.yml: Prometheus remote write 수신 활성화 및 포트 외부 노출
  • run.ps1: 기본값 운영 서버 주소로 변경
  • k6-dashboard.json: event_spike 시나리오명 동기화, 심화 지표 패널 4개 추가

📢 기능 설명

필요시 실행결과 스크린샷 첨부

연결된 issue

연결된 issue를 자동을 닫기 위해 아래 {이슈넘버}를 입력해주세요.

close #{이슈넘버}

✅ 체크리스트

  • PR 제목 규칙 잘 지켰는가?
  • 추가/수정사항을 설명하였는가?
  • 이슈넘버를 적었는가?

- 01·03·05·06·07번: event_spike(워밍업 후 스파이크) + ramp_up(점진 증가) 두 시나리오 적용
- 04번: ramp_up 단독으로 서킷브레이커 OPEN 시점 탐색 시나리오로 개선
- docker-compose.prod.yml: Prometheus remote write 수신 활성화 및 포트 외부 노출
- run.ps1: 기본값 운영 서버 주소로 변경
- k6-dashboard.json: event_spike 시나리오명 동기화, 심화 지표 패널 4개 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the k6 load testing suite to compare 'event_spike' and 'ramp_up' scenarios, introduces a Grafana dashboard for real-time monitoring, and configures Prometheus remote write. Key feedback includes addressing a security vulnerability where Prometheus port 9090 is exposed publicly in production, correcting k6 timeout options to use millisecond numbers instead of string formats (e.g., '65s' and '15s'), URL-encoding Korean characters in district queries, and refactoring date calculations to prevent timezone-related inconsistencies.

Comment thread docker-compose.prod.yml
Comment on lines +83 to +84
ports:
- "9090:9090"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

운영 환경(docker-compose.prod.yml)에서 Prometheus 포트(9090)를 외부(0.0.0.0:9090)에 그대로 노출하는 것은 보안상 매우 위험합니다. 특히 --web.enable-lifecycle 옵션이 활성화되어 있어 누구나 HTTP POST 요청을 통해 설정을 재로드하거나 Prometheus 서버를 종료할 수 있으며, 메트릭 데이터가 외부에 무방비로 노출됩니다.

외부 k6 등에서 remote write를 수신해야 하는 경우, 포트를 직접 노출하기보다는 Nginx 등의 리버스 프록시를 통해 SSL 및 Basic Authentication(기본 인증)을 적용하여 /api/v1/write 경로만 안전하게 노출하는 것을 권장합니다. 만약 내부 통신만 필요하다면 ports 대신 expose를 사용하거나 127.0.0.1:9090:9090과 같이 로컬 루프백에만 바인딩해야 합니다.

Comment thread k6/04-circuit-breaker.js
const res = http.post(`${BASE_URL}/api/v1/chat/messages`, payload, {
headers: HEADERS_AUTH,
timeout: 65000, // LLM 응답 최대 대기 (65초)
timeout: '65s',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

k6의 http.post API에서 timeout 옵션은 밀리초(ms) 단위의 **숫자(number)**를 인자로 받습니다. '65s'와 같은 문자열을 지정하면 k6가 올바르게 인식하지 못하거나 기본값(60초)으로 동작할 수 있으므로, 65000과 같이 밀리초 단위의 숫자로 설정해야 합니다.

Suggested change
timeout: '65s',
timeout: 65000,

Comment thread k6/06-store-nearby.js
`&centerLat=${lat}&centerLng=${lng}&limit=50`;

const res = http.get(url, { headers: HEADERS_JSON, timeout: 15000 });
const res = http.get(url, { headers: HEADERS_JSON, timeout: '15s' });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

k6의 http.get API에서 timeout 옵션은 밀리초(ms) 단위의 **숫자(number)**를 인자로 받습니다. '15s'와 같은 문자열 대신 15000과 같이 밀리초 단위의 숫자로 설정해야 올바르게 동작합니다.

Suggested change
const res = http.get(url, { headers: HEADERS_JSON, timeout: '15s' });
const res = http.get(url, { headers: HEADERS_JSON, timeout: 15000 });

Comment thread k6/05-store-list.js Outdated
if (useFilter) {
// 필터 조합을 랜덤하게 — 카테고리만, 지역만, 둘 다 섞어서 테스트
if (Math.random() > 0.5) url += `&category=${randomCategory}`;
if (Math.random() > 0.5) url += `&district=${randomDistrict}`;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

randomDistrict 변수에는 '강남구', '마포구' 등 한글 문자열이 포함되어 있습니다. URL에 한글과 같은 비ASCII 문자를 인코딩 없이 직접 추가하면, k6가 요청을 보낼 때 URI가 올바르지 않거나 서버에서 파라미터를 정상적으로 디코딩하지 못해 에러가 발생할 수 있습니다. 따라서 encodeURIComponent()를 사용하여 안전하게 인코딩하는 것이 좋습니다.

Suggested change
if (Math.random() > 0.5) url += `&district=${randomDistrict}`;
if (Math.random() > 0.5) url += '&district=' + encodeURIComponent(randomDistrict);

Comment thread k6/07-remains.js Outdated
Comment on lines 85 to 88
const today = new Date(Date.now() + 9 * 60 * 60 * 1000);
const dayOffset = Math.floor(Math.random() * 7); // 0~6일 후
const dayOffset = Math.floor(Math.random() * 7);
today.setDate(today.getDate() + dayOffset);
const date = today.toISOString().split('T')[0];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

new Date()로 생성된 객체에서 getDate()setDate()를 호출하면 실행 환경(OS/로컬 PC)의 타임존에 영향을 받습니다. 반면 toISOString()은 항상 UTC 기준으로 변환하므로, 실행 환경의 타임존에 따라 날짜 계산이 비일관적으로 동작할 수 있습니다.

타임존에 무관하게 일관된 날짜 계산을 하려면, 모든 계산을 밀리초(ms) 단위로 처리한 후 최종적으로 toISOString()을 호출하는 방식이 훨씬 안전하고 직관적입니다.

Suggested change
const today = new Date(Date.now() + 9 * 60 * 60 * 1000);
const dayOffset = Math.floor(Math.random() * 7); // 0~6일 후
const dayOffset = Math.floor(Math.random() * 7);
today.setDate(today.getDate() + dayOffset);
const date = today.toISOString().split('T')[0];
const todayMs = Date.now() + 9 * 60 * 60 * 1000;
const dayOffset = Math.floor(Math.random() * 7);
const date = new Date(todayMs + dayOffset * 24 * 60 * 60 * 1000).toISOString().split('T')[0];

- 05: district 파라미터 한글 encodeURIComponent 적용
- 07: setDate/getDate 타임존 혼용 → ms 연산으로 통일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@docodocod
docodocod merged commit d64d6dd into develop May 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant